package renmopr.tourguide.controller;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.kit.HttpKit;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.upload.UploadFile;

import renmopr.tourguide.dao.Photo;
import renmopr.tourguide.dao.Place;
import renmopr.tourguide.dao.PlaceNews;
import renmopr.tourguide.util.DateUtil;
import renmopr.tourguide.util.TextUtil;

public class BackstageController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(BackstageController.class);
	private static final String uploadImagePath = PropKit.get("uploadImagePath");
	private static final String imageUrl = PropKit.get("imageUrl");
	private static final int pageSize = 10;
	private static final String adminPwd = PropKit.get("adminPwd");
	private static final String guestPwd = PropKit.get("guestPwd");

	/**
	 * 验证登录
	 */
	public void login() {
		//getResponse().addHeader("Access-Control-Allow-Origin", "*");
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		@SuppressWarnings("unchecked")
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		String username = (String) params.get("username");
		String password = (String) params.get("password");
		String token = null;
		// admin 用户登录
		if ("admin".equals(username)) {
			// admin 用户密码
			if (!adminPwd.equals(password)) {
				map.put("code", 30000);
				map.put("message", "登录失败");
				renderJson(map);
				return;
			}
			token = "admin";
		}
		// guset 用户登录
		if ("guest".equals(username)) {
			// 检查 guest 密码
			if (!guestPwd.equals(password)) {
				map.put("code", 30000);
				map.put("message", "登录失败");
				renderJson(map);
				return;
			}
			token = "guest";
		}
		if (TextUtil.isEmpty(token)) {
			map.put("code", 30000);
			map.put("message", "登录失败");
			renderJson(map);
			return;
		}
		getSession().setAttribute("token", token);
		getSession().setMaxInactiveInterval(1800);
		map.put("token", token);
		map.put("code", 20000);
		map.put("message", "成功");
		renderJson(map);
	}

	/**
	 * 获取权限等信息
	 */
	public void getInfo() {
		Map<String, Object> map = new HashMap<String, Object>();
		String token = (String) getSession().getAttribute("token");
		String[] roles = new String[1];
		if ("admin".equals(token)) {
			roles[0] = "admin";
			map.put("roles", roles);
			map.put("introduction", "i am from back stage");
			map.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
			map.put("name", "Super Admin");
		}
		if ("guest".equals(token)) {
			roles[0] = "guest";
			map.put("roles", roles);
			map.put("introduction", "i am from back stage");
			map.put("avatar", "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
			map.put("name", "Guest");
		}

		map.put("code", 20000);
		map.put("message", "成功");
		renderJson(map);
	}

	public void logout() {
		HttpSession session = getSession();
		if (session != null) {
			getSession().invalidate();
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", 20000);
		map.put("desc", "成功");
		renderJson(map);
	}
	
	/**
	 * 上传图片
	 */
	public void uploadPhoto() {
		Map<String, Object> map = new HashMap<String, Object>();
		List<UploadFile> list = getFiles(uploadImagePath);
		int id = getParaToInt("id");
		if (list == null || list.size() == 0) {
			map.put("code", 20000);
			map.put("desc", "没有数据");
			renderJson(JsonKit.toJson(map));
			return;
		}

		String fileName = null;
		for (UploadFile file : list) {
			fileName = StrKit.getRandomUUID()
					+ file.getOriginalFileName().substring(file.getOriginalFileName().lastIndexOf("."));
			file.getFile().renameTo(new File(PropKit.get("uploadPath") + uploadImagePath + fileName));
			boolean result = new Photo().set("thumb_url", PropKit.get("imageUrl") + fileName)
					.set("img_url", PropKit.get("imageUrl") + fileName).set("place_id", id).set("sort_order", 0).save();
		    Place place = Place.dao.findById(id);
		    if (result && (null == place.getStr("img_url") || place.getStr("img_url").equals(""))) {
				result = place.set("img_url", imageUrl + fileName).update();
			}

			if (!result) {
				logger.info("can't insert file: " + file.getOriginalFileName() + " to photo");
				map.put("code", -1);
				map.put("desc", "操作失败");
				map.put("status", "false");
				renderJson(JsonKit.toJson(map));
				return;
			}
		}
		map.put("url", imageUrl + fileName);
		map.put("code", 20000);
		map.put("status", "success");
		map.put("desc", "成功");
		renderJson(JsonKit.toJson(map));
	}
	
	public void init() {
		Map<String, Object> map = new HashMap<String, Object>();
		int currentPage = getParaToInt("currentPage") * pageSize;
		int total = Place.dao.findFirst("select count(1) as total from place").getInt("total");
		List<Place> list = Place.dao.find("select *, '' as photos from place order by id limit ?, ?", currentPage, pageSize);
		List<String> placeIdList = list.stream().map(m -> {
			return m.getInt("id").toString();
		}).collect(Collectors.toList());
		String placeIds = String.join(",", placeIdList);
		List<Photo> photoList = Photo.dao.find("select * from photo where place_id in (" + placeIds +") order by sort_order asc");
		for (Place place : list) {
			List<Photo> photos = photoList.stream().filter(m -> m.getInt("place_id").equals(place.getInt("id"))).collect(Collectors.toList());
			place.setOrPut("photos", photos);
		}
		map.put("pageSize", pageSize);
		map.put("total", total);
		map.put("list", list);
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}
	
	public void getDetail() {
		Map<String, Object> map = new HashMap<String, Object>();
		Place p = Place.dao.findById(getParaToInt("id"));
		map.put("place", p);
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}
	
	public void update() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		@SuppressWarnings("unchecked")
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		int id = (int)params.get("id");
		String name = (String) params.get("name");
		String disctrict = (String) params.get("disctrict");
		String type = (String) params.get("type");
		String desc = (String) params.get("desc");
		String address = (String) params.get("address");
		String imgUrl = (String) params.get("imgUrl");
		
		Place p = Place.dao.findById(id);
		if (!TextUtil.isEmpty(name)) {
			p.set("name", name);
		}
		if (!TextUtil.isEmpty(disctrict)) {
			p.set("disctrict", disctrict);
		}
		if (!TextUtil.isEmpty(type)) {
			p.set("type", type);
		}
		if (!TextUtil.isEmpty(desc)) {
			p.set("desc", desc);
		}
		if (!TextUtil.isEmpty(desc)) {
			p.set("desc", desc);
		}
		if (!TextUtil.isEmpty(address)) {
			p.set("address", address);
		}
		if (!TextUtil.isEmpty(imgUrl)) {
			p.set("imgUrl", imgUrl);
		}
		p.update();
		
		map.put("list", Place.dao.findAll());
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}

	public void deletePhoto() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		int id = (int)params.get("id");

		Photo.dao.deleteById(id);

		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}

	public void sortPhoto() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		int id = (int)params.get("id");
		String direction = (String) params.get("direction");
		Photo photo = Photo.dao.findById(id);
		List<Photo> photos = Photo.dao.find("select * from photo where place_id=? order by sort_order asc", (Integer)photo.get("place_id"));
		for (int i = 0; i < photos.size(); i++) {
			Photo item = photos.get(i);
			item.set("sort_order", i);
		}
		for (int i = 0; i < photos.size(); i++) {
			if (photo.get("id").equals(photos.get(i).get("id"))) {
				if (direction.equals("up") && !photo.get("id").equals(photos.get(photos.size() - 1).get("id"))) {
					Photo item = photos.get(i);
					item.set("sort_order", i + 1);
					Photo item2 = photos.get(i + 1);
					item2.set("sort_order", i);
				} else if (direction.equals("down") && !photo.get("id").equals(photos.get(0).get("id"))) {
					Photo item = photos.get(i);
					item.set("sort_order", i - 1);
					Photo item2 = photos.get(i - 1);
					item2.set("sort_order", i);
				}
			}
		}
		for (int i = 0; i < photos.size(); i++) {
			Photo item = photos.get(i);
			item.update();
		}
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}


	public void search() {
		Map<String, Object> map = new HashMap<String, Object>();
		String word = getPara("word");
		int pageNo = getParaToInt("pageNo");
		if (TextUtil.isEmpty(word)) {
			map.put("code", 30001);
			map.put("message", "参数不全");
			renderJson(map);
			return;
		}
		String[] param = word.split(" ");
		if (param != null && param.length > 0) {
			List<Object> conditionList = new ArrayList<Object>(param.length * 2);
			StringBuffer sb = new StringBuffer();
			sb.append(" and (name like ? or address like ?");
			conditionList.add("%" + param[0] + "%");
			conditionList.add("%" + param[0] + "%");
			for(int i=1; i<param.length; i++) {
				sb.append(" or name like ? or address like ?");
				conditionList.add("%" + param[i] + "%");
				conditionList.add("%" + param[i] + "%");
			}
			sb.append(" )");
			int total = Place.dao.findFirst("select count(1) as total from place where 1=1" + sb.toString(), conditionList.toArray()).getInt("total");
			if (total > 0) {
				sb.insert(0, "select * from place where 1 = 1");
				// 添加分页及参数
				sb.append(" order by id limit ?, ?");
				conditionList.add(Integer.valueOf(pageNo));
				conditionList.add(Integer.valueOf(pageSize));
				
				List<Place> list = Place.dao.find(sb.toString(), conditionList.toArray());
				List<String> placeIdList = list.stream().map(m -> {
					return m.getInt("id").toString();
				}).collect(Collectors.toList());
				String placeIds = String.join(",", placeIdList);
				List<Photo> photoList = Photo.dao.find("select * from photo where place_id in (" + placeIds +") order by sort_order asc");
				for (Place place : list) {
					List<Photo> photos = photoList.stream().filter(m -> m.getInt("place_id").equals(place.getInt("id"))).collect(Collectors.toList());
					place.setOrPut("photos", photos);
				}
				if (list != null && list.size() >0) {
					map.put("list", list);
					map.put("total", total);
				}
			}
		}
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(map);
	}
	
//	百度坐标转高德坐标	
//	public void updateGeom() {
//		List<Place> list = Place.dao.findAll();
//		for (Place place : list) {
//			double lat = Double.valueOf(place.getStr("lat"));
//			double lon = Double.valueOf(place.getStr("lon"));
//			double[] gdPoint = bdToGaoDe(lat, lon);
//			if (Db.update("update place p set `lon` = ? , lat = ? where id = ?", Double.toString(gdPoint[0]), Double.toString(gdPoint[1]), place.getInt("id")) != 1) {
//				logger.error("place id:" + place.getInt("id") + "can't update");
//			}
//		}
//	}
//	
//	private double[] bdToGaoDe(double bd_lat, double bd_lon) {
//	    double[] gd_lat_lon = new double[2];
//	    double PI = 3.14159265358979324 * 3000.0 / 180.0;
//	    double x = bd_lon - 0.0065, y = bd_lat - 0.006;
//	    double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);
//	    double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);
//	    gd_lat_lon[0] = z * Math.cos(theta);
//	    gd_lat_lon[1] = z * Math.sin(theta);
//	    return gd_lat_lon;
//	}

	public void createNews() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		@SuppressWarnings("unchecked")
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		Integer placeId = (Integer) params.get("place_id");
		String title = (String) params.get("title");
		String content = (String) params.get("content");
		String type = (String) params.get("type");
		String version = (String) params.get("version");
		String publishTime = (String) params.get("publish_time");

		Boolean valid = true;
		if (TextUtil.isEmpty(title)) {
			map.put("code", 40000);
			map.put("message", "标题不能为空");
			valid = false;
		}
		if (null == type) {
			map.put("code", 40000);
			map.put("message", "请选择类型");
			renderJson(JsonKit.toJson(map));
			valid = false;
		}
		if (valid) {
			PlaceNews placeNews = new PlaceNews();
			placeNews.set("place_id", placeId);
			placeNews.set("title", title);
			if (!TextUtil.isEmpty(content)) {
				placeNews.set("content", content);
			}
			placeNews.set("type", type);
			if (!TextUtil.isEmpty(version)) {
				placeNews.set("version", version);
			}

			if (publishTime != null) {
				placeNews.set("publish_time", publishTime);
			}

			placeNews.save();

			map.put("code", 20000);
			map.put("message", "SUCCESS");
			renderJson(JsonKit.toJson(map));
			return;
		}
		renderJson(JsonKit.toJson(map));
	}

	public void updateNews() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		@SuppressWarnings("unchecked")
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		Integer id = (Integer) params.get("id");
		String title = (String) params.get("title");
		String content = (String) params.get("content");
		String type = (String) params.get("type");
		String version = (String) params.get("version");
		String publishTime = (String) params.get("publish_time");

		Boolean valid = true;
		if (TextUtil.isEmpty(title)) {
			map.put("code", 40000);
			map.put("message", "标题不能为空");
			valid = false;
		}
		if (null == type) {
			map.put("code", 40000);
			map.put("message", "请选择类型");
			renderJson(JsonKit.toJson(map));
			valid = false;
		}
		if (valid) {
			PlaceNews placeNews = PlaceNews.dao.findById(id);
			placeNews.set("title", title);
			if (!TextUtil.isEmpty(content)) {
				placeNews.set("content", content);
			}
			placeNews.set("type", type);
			if (!TextUtil.isEmpty(version)) {
				placeNews.set("version", version);
			}

			if (publishTime != null) {
				placeNews.set("publish_time", publishTime);
			}

			placeNews.update();

			map.put("code", 20000);
			map.put("message", "SUCCESS");
			renderJson(JsonKit.toJson(map));
			return;
		}
		renderJson(JsonKit.toJson(map));
	}

	public void news() {
		Map<String, Object> map = new HashMap<String, Object>();
		int id = getParaToInt("id");
		PlaceNews news = PlaceNews.dao.findById(id);
		map.put("data", news);
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}

	public void listNews() {
		Map<String, Object> map = new HashMap<String, Object>();
		int currentPage = getParaToInt("currentPage", 0) * pageSize;
		int placeId = getParaToInt("place_id");
		int total = PlaceNews.dao.findFirst("select count(1) as total from place_news where place_id=?", placeId).getInt("total");
		List<PlaceNews> list = PlaceNews.dao.find("select * from place_news where place_id=? order by id", placeId);

		map.put("pageSize", pageSize);
		map.put("total", total);
		map.put("list", list);
		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}

	public void deleteNews() {
		Map<String, Object> map = new HashMap<String, Object>();
		String jsonString = HttpKit.readData(getRequest());
		Map<String, Object> params = JsonKit.parse(jsonString, HashMap.class);
		int id = (int)params.get("id");

		PlaceNews.dao.deleteById(id);

		map.put("code", 20000);
		map.put("message", "SUCCESS");
		renderJson(JsonKit.toJson(map));
	}

	public void upload() {
		Map<String, Object> map = new HashMap<String, Object>();
		List<UploadFile> list = getFiles(uploadImagePath);
		if (list == null || list.size() == 0) {
			map.put("code", 20000);
			map.put("desc", "没有数据");
			renderJson(JsonKit.toJson(map));
			return;
		}

		String fileName = null;
		for (UploadFile file : list) {
			fileName = StrKit.getRandomUUID()
					+ file.getOriginalFileName().substring(file.getOriginalFileName().lastIndexOf("."));
			file.getFile().renameTo(new File(PropKit.get("uploadPath") + uploadImagePath + fileName));
		}
		map.put("url", imageUrl + fileName);
		map.put("code", 20000);
		map.put("status", "success");
		map.put("desc", "成功");
		renderJson(JsonKit.toJson(map));
	}
}
